package cn.kgm.makeGod.condition;

import cn.kgm.makeGod.Character;
import cn.kgm.makeGod.*;
import cn.kgm.makeGod.action.Action;
import cn.kgm.makeGod.action.CultivateAction;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;

/**
 * @Version 1.8
 * @Author: Kappi
 * @Date: 2025-9-11 11:31
 * @Description: cn.kgm.makeGod.condition.WorldState
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WorldState {
    private Map<Integer, Character> characters = new HashMap<>();
    private Map<Integer, Location> locations = new HashMap<>();
    private List<GameEvent> events = new ArrayList<>();
    private int currentMonth = 0;
    // 新增的属性
    private Map<Integer, Item> items = new HashMap<>(); // 所有物品
    private Map<Integer, ResourceNode> resourceNodes = new HashMap<>(); // 资源点
    private List<ItemOwnership> itemOwnerships = new ArrayList<>(); // 物品所有权

    /**
     * 扩展的资源争抢方法 - 加入土遁符检查
     */
    public static void competeForResourceWithEscapeCheck(WorldState world, int resourceId, Location location, List<Character> characters) {
        // 检查是否有角色使用土遁符逃跑
        List<Character> remainingCharacters = new ArrayList<>();
        for (Character character : characters) {
            boolean shouldFlee = false;

            // 检查是否有明显更强的对手
            for (Character other : characters) {
                if (other.getId() != character.getId()) {
                    int characterPower = ResourceCompetitionSystem.calculateCombatPower(character);
                    int otherPower = ResourceCompetitionSystem.calculateCombatPower(other);

                    if (otherPower > characterPower + 300) { // 对手明显更强
                        // 根据性格决定是否逃跑
                        if (ResourceCompetitionSystem.shouldUseTalisman(character, otherPower - characterPower)) {
                            if (ResourceCompetitionSystem.useEarthEscapeTalisman(world, character, other)) {
                                shouldFlee = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (!shouldFlee) {
                remainingCharacters.add(character);
            }
        }
        characters = remainingCharacters;
    }

    public void addCharacter(Character character) {
        characters.put(character.getId(), character);
    }

    public void removeCharacter(Character character) {
        characters.remove(character.getId());
    }

    public void addLocation(Location location) {
        locations.put(location.getId(), location);
    }

    public void addEvent(GameEvent event) {
        events.add(event);
    }

    public Character getCharacter(int id) {
        return characters.get(id);
    }

    public Location getLocation(int id) {
        return locations.get(id);
    }

    private void moveCharacters() {
        Random random = new Random();
        for (Character character : characters.values()) {
            // 简单随机移动逻辑
            if (random.nextInt(100) < 90) { // 30%概率移动
                int locationId = random.nextInt(locations.size()) + 1;
                character.setCurrentLocation(locations.get(locationId));
                System.out.println(character.getName() + " 移动到了 " +
                        character.getCurrentLocation().getName());
            }
        }
    }

    /**
     * 检查并使用土遁符
     */
    private void checkAndUseTalisman(Character character) {
        // 检查当前位置是否有明显更强的对手
        List<Character> strongerOpponents = new ArrayList<>();
        int characterPower = ResourceCompetitionSystem.calculateCombatPower(character);

        for (Character other : characters.values()) {
            if (other.getId() != character.getId() &&
                    other.getCurrentLocation().getId() == character.getCurrentLocation().getId()) {
                int otherPower = ResourceCompetitionSystem.calculateCombatPower(other);
                if (otherPower > characterPower + 20) { // 对手明显更强
                    strongerOpponents.add(other);
                }
            }
        }

        if (!strongerOpponents.isEmpty()) {
            // 随机选择一个强对手
            Character opponent = strongerOpponents.get(new Random().nextInt(strongerOpponents.size()));

            // 根据性格决定是否使用土遁符
            if (shouldUseTalismanPreemptively(character, opponent)) {
                ResourceCompetitionSystem.useEarthEscapeTalisman(this, character, opponent);
            }
        }
    }

    /**
     * 判断是否预先使用土遁符
     */
    private boolean shouldUseTalismanPreemptively(Character character, Character opponent) {
        int baseChance = 30; // 基础使用概率

        // 性格影响
        if (character.hasPersonality(PersonalityTag.GRUDGE, 60)) {
            baseChance -= 15; // 记仇的人不太可能预先逃跑
        }
        if (character.hasPersonality(PersonalityTag.ARROGANT, 60)) {
            baseChance -= 20; // 傲慢的人不太可能预先逃跑
        }
        if (character.hasPersonality(PersonalityTag.SELFISH, 50)) {
            baseChance += 20; // 自私的人更可能预先逃跑
        }
        if (character.hasPersonality(PersonalityTag.KIND, 60)) {
            baseChance += 10; // 善良的人可能选择预先逃跑避免冲突
        }

        // 实力差距影响
        int characterPower = ResourceCompetitionSystem.calculateCombatPower(character);
        int opponentPower = ResourceCompetitionSystem.calculateCombatPower(opponent);
        int powerDifference = opponentPower - characterPower;
        baseChance += Math.min(40, powerDifference / 3);

        // 检查是否有土遁符
        boolean hasTalisman = getItemsOwnedBy(character.getId()).stream()
                .anyMatch(io -> io.getItemId() == 7 || io.getItemId() == 8);

        if (!hasTalisman) {
            return false;
        }

        Random random = new Random();
        return random.nextInt(100) < Math.max(5, Math.min(80, baseChance));
    }

    // 添加物品转移方法
    public boolean transferItem(int fromCharacterId, int toCharacterId, int itemId, int quantity) {
        // 检查来源角色是否拥有该物品
        ItemOwnership fromOwnership = null;
        for (ItemOwnership ownership : itemOwnerships) {
            if (ownership.getCharacterId() == fromCharacterId && ownership.getItemId() == itemId) {
                fromOwnership = ownership;
                break;
            }
        }

        if (fromOwnership == null || fromOwnership.getQuantity() < quantity) {
            return false; // 来源角色没有足够的物品
        }

        // 减少来源角色的物品数量
        fromOwnership.setQuantity(fromOwnership.getQuantity() - quantity);

        // 如果数量为0，移除记录
        if (fromOwnership.getQuantity() == 0) {
            itemOwnerships.remove(fromOwnership);
        }

        // 增加目标角色的物品数量
        acquireItem(toCharacterId, itemId, quantity);

        return true;
    }

    // 扩展的模拟方法
    public void simulateMonth() {
        currentMonth++;
        System.out.println("===== 第 " + currentMonth + " 月 =====");

        // 1. 更新资源点
        updateResourceNodes();

        // 2. 角色移动
        moveCharacters();

        // 3. 检查资源争抢
        checkResourceCompetitions();

        // 4. 角色自主行动 - 修炼、寻宝、争抢资源等
        autonomousActions();

        // 5. 检查事件触发
        checkEvents();
    }

    // 检查所有位置的资源争抢
    private void checkResourceCompetitions() {
        for (Location location : locations.values()) {
            ResourceCompetitionSystem.checkResourceCompetition(this, location);
        }
    }

    private void autonomousActions() {
        Random random = new Random();
        // 创建副本以避免 ConcurrentModificationException
        List<Character> charactersCopy = new ArrayList<>(characters.values());

        for (Character character : charactersCopy) {
            // 确保角色仍然存在于原始集合中
            if (!characters.containsValue(character)) {
                continue;
            }

            // 30%概率进行自主行动
            if (random.nextInt(100) < 30) {
                int actionType = random.nextInt(7); // 现在有7种行动类型 (0-6)

                switch (actionType) {
                    case 0: // 修炼
                        CultivateAction cultivate = new CultivateAction(false);
                        EventResult result = new EventResult();
                        cultivate.execute(character, character, this, result);
                        for (String log : result.getLogs()) {
                            System.out.println("  - " + log);
                        }
                        break;

                    case 1: // 寻宝（只有野外可以）
                        if (character.getCurrentLocation().getType() == LocationType.WILD ||
                                character.getCurrentLocation().getType() == LocationType.DUNGEON) {
                            System.out.println(character.getName() + " 在 " +
                                    character.getCurrentLocation().getName() + " 寻找宝物");
                            // 简化寻宝逻辑
                            if (random.nextInt(100) < character.getLuck()) {
                                System.out.println("  - " + character.getName() + " 找到了一件宝物!");
                                character.setLevel(character.getLevel() + 1);
                            }
                        }
                        break;

                    case 2: // 回城补给（只有野外可以）
                        if (character.getCurrentLocation().getType() == LocationType.WILD ||
                                character.getCurrentLocation().getType() == LocationType.DUNGEON) {
                            if (random.nextInt(100) < 40) {
                                // 找到最近的城市
                                Location city = findNearestLocation(character.getCurrentLocation(), LocationType.CITY);
                                if (city != null) {
                                    character.setCurrentLocation(city);
                                    System.out.println(character.getName() + " 回到 " + city.getName() + " 进行补给");
                                }
                            }
                        }
                        break;

                    case 3: // 主动争抢资源
                        initiateResourceCompetition(character);
                        break;

                    case 4: // 采集资源
                        gatherResources(character);
                        break;

                    case 5: // 疗伤
                        if (character.getCurrentHp() < character.getMaxHp() * 0.7) {
                            System.out.println(character.getName() + " 正在运功疗伤");
                            character.setCurrentHp(character.getCurrentHp() + character.getLevel() * 2);
                            System.out.println("  - " + character.getName() + " 恢复了生命值");
                        }
                        break;

                    case 6: // 检查并使用土遁符（如果处于危险中）
                        checkAndUseTalisman(character);
                        break;
                }
            }
        }
    }

    // 主动发起资源争抢
    private void initiateResourceCompetition(Character character) {
        // 检查当前位置是否有可用资源
        for (ResourceNode node : resourceNodes.values()) {
            if (node.getLocation().getId() == character.getCurrentLocation().getId() && node.isAvailable()) {
                // 检查是否有其他角色在同一位置
                List<Character> competitors = new ArrayList<>();
                for (Character c : characters.values()) {
                    if (c.getId() != character.getId() &&
                            c.getCurrentLocation().getId() == character.getCurrentLocation().getId()) {
                        competitors.add(c);
                    }
                }

                if (!competitors.isEmpty()) {
                    // 随机选择一个竞争对手
                    Character target = competitors.get(new Random().nextInt(competitors.size()));

                    // 根据性格决定是否发起争抢
                    if (shouldInitiateCompetition(character, target, node.getItemId())) {
                        System.out.println(character.getName() + " 决定与 " + target.getName() +
                                " 争夺 " + getItem(node.getItemId()).getName());

                        // 触发争抢
                        int winnerId = ResourceCompetitionSystem.competeForResource(
                                this, node.getItemId(), character.getCurrentLocation(),
                                Arrays.asList(character, target));

                        // 如果确定了胜利者，标记资源为已采集
                        if (winnerId != -1) {
                            node.harvest();
                        }
                    }
                }
                break;
            }
        }
    }

    // 判断是否发起争抢
    private boolean shouldInitiateCompetition(Character initiator, Character target, int resourceId) {
        int baseChance = 40;

        // 性格影响
        if (initiator.hasPersonality(PersonalityTag.EVIL, 50)) {
            baseChance += 20;
        }
        if (initiator.hasPersonality(PersonalityTag.SELFISH, 50)) {
            baseChance += 15;
        }
        if (initiator.hasPersonality(PersonalityTag.KIND, 60)) {
            baseChance -= 25;
        }
        if (initiator.hasPersonality(PersonalityTag.LOYAL, 60) &&
                initiator.getRelationshipTo(target.getId()) != null &&
                initiator.getRelationshipTo(target.getId()).getValue() > 30) {
            baseChance -= 30; // 对朋友不太可能争抢
        }

        // 资源价值影响
        int resourceValue = ResourceCompetitionSystem.RESOURCE_VALUES.getOrDefault(resourceId, 100);
        baseChance += resourceValue / 40;

        // 战斗力差距影响
        int initiatorPower = ResourceCompetitionSystem.calculateCombatPower(initiator);
        int targetPower = ResourceCompetitionSystem.calculateCombatPower(target);
        if (initiatorPower > targetPower) {
            baseChance += 15; // 比自己弱的更可能攻击
        } else {
            baseChance -= 10; // 比自己强的不太可能攻击
        }

        Random random = new Random();
        return random.nextInt(100) < Math.max(5, Math.min(95, baseChance));
    }

    private void checkEvents() {
        // 按位置分组角色
        Map<Location, List<Character>> charactersByLocation = new HashMap<>();
        for (Character character : characters.values()) {
            Location loc = character.getCurrentLocation();
            charactersByLocation.computeIfAbsent(loc, k -> new ArrayList<>()).add(character);
        }

        // 检查每个位置的角色互动
        for (List<Character> charactersAtLocation : charactersByLocation.values()) {
            if (charactersAtLocation.size() < 2) continue;

            // 检查每对角色
            for (int i = 0; i < charactersAtLocation.size(); i++) {
                for (int j = i + 1; j < charactersAtLocation.size(); j++) {
                    Character actor = charactersAtLocation.get(i);
                    Character target = charactersAtLocation.get(j);

                    checkEventsForPair(actor, target);
                }
            }
        }
    }

    // 添加物品
    public void addItem(Item item) {
        items.put(item.getId(), item);
    }

    // 添加资源点
    public void addResourceNode(ResourceNode node) {
        resourceNodes.put(node.getId(), node);
    }

    // 添加物品所有权
    public void addItemOwnership(ItemOwnership ownership) {
        itemOwnerships.add(ownership);
    }

    // 获取角色拥有的物品
    public List<ItemOwnership> getItemsOwnedBy(int characterId) {
        List<ItemOwnership> result = new ArrayList<>();
        for (ItemOwnership ownership : itemOwnerships) {
            if (ownership.getCharacterId() == characterId) {
                result.add(ownership);
            }
        }
        return result;
    }

    // 获取物品信息
    public Item getItem(int itemId) {
        return items.get(itemId);
    }

    // 角色获得物品
    public void acquireItem(int characterId, int itemId, int quantity) {
        // 检查是否已经拥有该物品
        for (ItemOwnership ownership : itemOwnerships) {
            if (ownership.getCharacterId() == characterId && ownership.getItemId() == itemId) {
                ownership.setQuantity(ownership.getQuantity() + quantity);
                return;
            }
        }

        // 如果没有，添加新的所有权记录
        itemOwnerships.add(new ItemOwnership(characterId, itemId, quantity));
    }

    // 角色使用物品
    public boolean useItem(int characterId, int itemId) {
        Character character = characters.get(characterId);
        Item item = items.get(itemId);

        if (character == null || item == null) {
            return false;
        }

        // 检查是否拥有该物品
        for (ItemOwnership ownership : itemOwnerships) {
            if (ownership.getCharacterId() == characterId && ownership.getItemId() == itemId) {
                if (ownership.getQuantity() > 0) {
                    // 应用物品效果
                    applyItemEffects(character, item);

                    // 减少数量
                    ownership.setQuantity(ownership.getQuantity() - 1);

                    // 如果数量为0，移除记录
                    if (ownership.getQuantity() == 0) {
                        itemOwnerships.remove(ownership);
                    }

                    return true;
                }
                break;
            }
        }

        return false;
    }

    // 应用物品效果
    private void applyItemEffects(Character character, Item item) {
        for (Map.Entry<String, Integer> effect : item.getEffects().entrySet()) {
            String attribute = effect.getKey();
            int value = effect.getValue();

            switch (attribute) {
                case "level":
                    character.setLevel(character.getLevel() + value);
                    break;
                case "charm":
                    character.setCharm(character.getCharm() + value);
                    break;
                case "luck":
                    character.setLuck(character.getLuck() + value);
                    break;
                case "attack":
                    character.setAttack(character.getAttack() + value);
                    break;
                case "defense":
                    character.setDefense(character.getDefense() + value);
                    break;
                case "maxHp":
                    character.setMaxHp(character.getMaxHp() + value);
                    break;
                case "currentHp":
                    int newHp = character.getCurrentHp() + value;
                    character.setCurrentHp(Math.min(newHp, character.getMaxHp()));
                    break;
            }
        }
    }

    // 更新资源点
    private void updateResourceNodes() {
        for (ResourceNode node : resourceNodes.values()) {
            node.update();
            if (node.isAvailable()) {
                System.out.println("资源点【" + node.getName() + "】已刷新");
            }
        }
    }

    // 争抢资源
    private void competeForResources(Character character) {
        // 检查酒馆中是否有其他角色
        List<Character> charactersInTavern = new ArrayList<>();
        for (Character c : characters.values()) {
            if (c.getId() != character.getId() &&
                    c.getCurrentLocation().getId() == character.getCurrentLocation().getId()) {
                charactersInTavern.add(c);
            }
        }

        if (!charactersInTavern.isEmpty()) {
            // 随机选择一个角色作为竞争对手
            Character competitor = charactersInTavern.get(new Random().nextInt(charactersInTavern.size()));

            // 创建争抢事件
            GameEvent competeEvent = createCompeteEvent();
            EventResult result = new EventResult();

            // 执行争抢事件
            if (competeEvent.checkConditions(character, competitor, this)) {
                competeEvent.executeActions(character, competitor, this, result);

                // 输出事件日志
                for (String log : result.getLogs()) {
                    System.out.println("  - " + log);
                }
            }
        }
    }

    // 采集资源
    private void gatherResources(Character character) {
        // 检查当前位置是否有资源点
        for (ResourceNode node : resourceNodes.values()) {
            if (node.getLocation().getId() == character.getCurrentLocation().getId() && node.isAvailable()) {
                System.out.println(character.getName() + " 在 " + node.getName() + " 采集资源");

                // 采集成功率基于运气
                Random random = new Random();
                if (random.nextInt(100) < character.getLuck()) {
                    if (node.harvest()) {
                        acquireItem(character.getId(), node.getItemId(), 1);
                        Item item = getItem(node.getItemId());
                        System.out.println("  - " + character.getName() + " 成功获得了 " + item.getName());
                    }
                } else {
                    System.out.println("  - " + character.getName() + " 采集失败");
                }
                break;
            }
        }
    }

    // 创建争抢事件
    private GameEvent createCompeteEvent() {
        GameEvent competeEvent = new GameEvent(100, "酒馆争抢", 100);

        // 条件：在酒馆
        competeEvent.getConditions().add(new LocationCondition(LocationType.TAVERN));

        // 动作：争抢逻辑
        competeEvent.getActions().add(new Action() {
            @Override
            public void execute(Character actor, Character target, WorldState world, EventResult result) {
                result.addLog(actor.getName() + " 和 " + target.getName() + " 在酒馆中为了万年蛇胎酒发生了争执!");

                // 决定争抢结果的因素：等级、攻击力、运气
                int actorPower = actor.getLevel() * 2 + actor.getAttack() + actor.getLuck() / 5;
                int targetPower = target.getLevel() * 2 + target.getAttack() + target.getLuck() / 5;

                // 加入随机因素
                Random random = new Random();
                actorPower += random.nextInt(20);
                targetPower += random.nextInt(20);

                if (actorPower > targetPower) {
                    result.addLog(actor.getName() + " 成功抢到了万年蛇胎酒!");

                    // 获得物品
                    world.acquireItem(actor.getId(), 1, 1); // 假设万年蛇胎酒的ID是1

                    // 关系变化
                    Relationship rel = actor.getRelationshipTo(target.getId());
                    if (rel != null) {
                        rel.setValue(rel.getValue() - 20);
                    } else {
                        actor.addRelationship(new Relationship(
                                actor.getId(), target.getId(),
                                RelationshipType.SWORN_ENEMY, -30
                        ));
                    }

                    // 目标也会记恨
                    Relationship targetRel = target.getRelationshipTo(actor.getId());
                    if (targetRel != null) {
                        targetRel.setValue(targetRel.getValue() - 30);
                    } else {
                        target.addRelationship(new Relationship(
                                target.getId(), actor.getId(),
                                RelationshipType.SWORN_ENEMY, -40
                        ));
                    }

                } else {
                    result.addLog(target.getName() + " 成功守住了万年蛇胎酒!");

                    // 关系变化
                    Relationship rel = actor.getRelationshipTo(target.getId());
                    if (rel != null) {
                        rel.setValue(rel.getValue() - 15);
                    } else {
                        actor.addRelationship(new Relationship(
                                actor.getId(), target.getId(),
                                RelationshipType.SWORN_ENEMY, -20
                        ));
                    }
                }
            }
        });

        return competeEvent;
    }

    // 查找最近的地点
    private Location findNearestLocation(Location currentLocation, LocationType type) {
        // 简化实现：随机返回一个指定类型的地点
        List<Location> matchingLocations = new ArrayList<>();
        for (Location location : locations.values()) {
            if (location.getType() == type) {
                matchingLocations.add(location);
            }
        }

        if (!matchingLocations.isEmpty()) {
            return matchingLocations.get(new Random().nextInt(matchingLocations.size()));
        }

        return null;
    }

    private void checkEventsForPair(Character actor, Character target) {
        Random random = new Random();

        for (GameEvent event : events) {
            // 检查触发概率
            if (random.nextInt(100) >= event.getTriggerChance()) {
                continue;
            }

            // 检查条件
            if (event.checkConditions(actor, target, this)) {
                EventResult result = new EventResult();
                result.addLog("触发事件: " + event.getName());

                // 执行事件动作
                event.executeActions(actor, target, this, result);

                // 输出事件日志
                for (String log : result.getLogs()) {
                    System.out.println("  - " + log);
                }

                // 一个角色对只触发一个事件
                break;
            }
        }
    }
}
